dojo.provide("novell.controls.tree.store.LazyLoadJSIStore");
dojo.require("dojo.data.ItemFileReadStore");

dojo.declare("novell.controls.tree.store.LazyLoadJSIStore", dojo.data.ItemFileReadStore, {
	constructor: function(/* object */ keywordParameters){
		// LazyLoadJSIStore extends ItemFileReadStore to implement an
		// example of lazy-loading/faulting in items on-demand.
		// Note this is certianly not a perfect implementation, it is
		// an example.
	},
	
	getItemById: function(/*string*/ id)
		{
			//console.debug("item in store is "+this._getItemByIdentity(id));
			var itemObject = this._getItemByIdentity(id);
			return itemObject;
		},
	
	isItemLoaded: function(/*object*/ item) {
		//	summary:
		//		Overload of the isItemLoaded function to look for items of type 'stub', which indicate
		//		the data hasn't been loaded in yet.
		//
		//	item:
		//		The item to examine.
		
		//For this store, if it has the value of stub for its type attribute,
		//then the item basn't been fully loaded yet.  It's just a placeholder.
		if(this.getValue(item, "type") === "stub"){
			//console.debug("stub is my type "+item.name+" "+item.id);
			
			return false;
		}
		return true;
	},
	
	/* dojo.data.api.Notification */

	onSetChildren: function(/* item */ childItem,/* item */ parentItem,
					/*attribute-name-string*/ attribute){
		// summary: See dojo.data.api.Notification.onSet()

		// No need to do anything. This method is here just so that the
		// client code can connect observers to it.
	},
		
	loadItem: function(keywordArgs){
		//	summary:
		//		Overload of the loadItem function to fault in items.  This assumes the data for an item is laid out
		//		in a RESTful sort of pattern name0/name1/data.json and so on and uses that to load the data.
		//		It will also detect stub items in the newly loaded item and insert the stubs into the ItemFileReadStore
		//		list so they can also be loaded in on-demand.
		//
		//	item:
		//		The item to examine.

		var item = keywordArgs.item;
		this._assertIsItem(item);

		//Build the path to the data.json for this item
		//The path consists of where its parent was loaded from
		//plus the item name.
		//var itemName = this.getValue(item, "name");
		var parent   = this.getValue(item, "parent");
		var ajaxClass   = this.getValue(item, "ajaxClass");
		var dataUrl  = this.url;


		//If there is a parent, it will append the stub to end of AjaxHandler class
		//if the call to get root node is AjaxHandler=AuditSettingsTreeAjax
		//the calls to get a stub will be AjaxHandler=AuditSettingsTreeAjax/<parent>/<itemname>/data.json
		//remember we will always call ajax rather than direct json files, becuase of localization requirements
		if (parent){			
			dataUrl += ("/" +parent + "/");		
			
		}
		dataUrl +=  "/data.json";
		
		//If we dont have json files locally, but everything dynamic in nature
		//then no data.json is required. Instaed all calls will be ajax
		//we use ajaxClass for that purpose
		//if ajaxClass is there, we take that, cant support both at the same time
		if(ajaxClass)
			{
				dataUrl  = this.url;
				//We need to remove already existing ajaxhandler there, it will be like .../AjaxServlet?AjaxHandler=....
				
				var index = dataUrl.lastIndexOf('?');
				dataUrl =  dataUrl.substring(0,index);
				dataUrl += "?AjaxHandler="+ajaxClass;
				//console.debug(dataUrl);
			}

		
		
		//console.debug(dataUrl);
		//Need a reference to the store to call back to its structures.
		var self = this;
		
		
		// Callback for handling a successful load.
		var gotData = function(data){
			//Now we need to modify the existing item a bit to take it out of stub state
			//Since we extend the store and have knowledge of the internal
			//structure, this can be done here.  Now, is we extended
			//a write store, we could call the write APIs to do this too
			//But for a simple demo the diretc modification in the store function
			//is sufficient.

			//Clear off the stub indicators.
			delete item.type;
			delete item.parent;
			//console.debug("my type is "+item.type);
			//this.setValue(item, "type", "eventgroup");
			var childArray=[];

			//Set up the loaded values in the format ItemFileReadStore uses for attributes.
			//console.debug("****************************************");
			var normalflow=true;
			for (var i in data) {
				if (dojo.isArray(data[i])) {
				//console.debug("****************************************"+data[i]);
					item[i] = data[i];
				}else{
					
					item[i] = [data[i]];
					//console.debug("****************************************"+[data[i]]);
					
					
				}
			}
			
			seen = [];
		//	JSON.stringify(item, function(key, val) {
		//	   if (typeof val == "object") {
		//			if (seen.indexOf(val) >= 0)
			//			return undefined
		//			seen.push(val)
		//		}
				//console.debug(val);
		//	});

			
			//Reset the item in the reference.
			self._arrayOfAllItems[item[self._itemNumPropName]] = item;
					//	console.debug("my type is "+item.type);
			//Scan the new values in the item for extra stub items we need to
			//add to the items array of the store so they can be lazy-loaded later...
			var attributes = self.getAttributes(item);
			for(i in attributes){
			
			//console.debug("Attribute  is "+attributes[i]);
			if(attributes[i] == "parentId")
					{
						
						  //console.debug("****************************************"+item[attributes[i]]);
						  var parenttobeUpdated = self._getItemByIdentity(item[attributes[i]]);
						  //console.debug(parenttobeUpdated[self._reverseRefMap]);
						  self._addReferenceToMap(item,parenttobeUpdated,"children");
					}
			
				var values = item[attributes[i]];
				for (var j = 0; j < values.length; j++) {
					var value = values[j];
							
					if(typeof value === "object"){
					
						if(value["stub"] ){
							//We have a stub reference here, we need to create the stub item
							 var stub = {
								type: ["stub"],
								name: [value["stub"]],	//
								parent: [itemName]
							 	
								
								//The child stub item is parented by this item name...
								
							};
							if (parent) {
								//Add in any parents to your parent so URL construstruction is accurate.
								stub.parent[0] = parent + "/" + stub.parent[0];
							}
							//console.debug(JSON.stringify(stub));
							//Finalize the addition of the new stub item into the ItemFileReadStore list.
							self._arrayOfAllItems.push(stub);
							
							
							stub[self._storeRefPropName] = self;
							stub[self._itemNumPropName] = (self._arrayOfAllItems.length - 1); //Last one pushed in should be the item
							values[j] = stub; //Set the stub item back in its place and replace the stub notation.
													
						}
												
						else//anjana
						{
						  //console.debug("child itself, no stub "+ [value["id"]]);
						  //console.debug(JSON.stringify(value));
						  var child = {
							id: [value["id"]],
							name: [value["name"]],
							type: [value["type"]],
							parent: [value["parent"]],
							icon:[value["icon"]],
							parentId: [value["parentId"]],
							ajaxClass:[value["ajaxClass"]],
							hasRights:[value["hasRights"]],
							hasLicense:[value["hasLicense"]],
							comp:[value["comp"]],
							rightsComp:[value["rightsComp"]],
							licComp:[value["licComp"]]
						  };

						// child=value;
						 self._arrayOfAllItems.push(child);
						 childArray.push(child);
						
						   child[self._storeRefPropName] = self;
							child[self._itemNumPropName] = (self._arrayOfAllItems.length - 1); //Last one pushed in should be the item
							//child[_reference]=self.getValue(item, "id");
							values[j] = child;
						//	console.debug("****************************************");
						//	console.debug(item[self._reverseRefMap]);
						//	console.debug("id is "+item.id);
							// var parenttobeUpdated = self._getItemByIdentity(item.id);
							//console.debug(parenttobeUpdated);
							 //console.debug(parenttobeUpdated[self._reverseRefMap]);
							//self._addReferenceToMap(child,item,"children");
							//var references =  {};
								
							//	var itemRef = references[item.id] = {};
								
							//	itemRef["children"] = true;
							
							//if(!self._itemsByIdentity[child.id]){
								self._itemsByIdentity[value["id"]] = child;
							//}
								//console.debug(references);
								//child[self._reverseRefMap]=references;
								
						}
						
					}
				}
			}
			
			//if(!self._itemsByIdentity[item.id] )
			//{
								self._itemsByIdentity[item.id] = item;
			//}
			//Done processing!  Call the onItem, if any.
			if(keywordArgs.onItem){
				//console.debug("keywodargs is "+keywordArgs);
				var scope = keywordArgs.scope ? keywordArgs.scope : dojo.global;
				
				
				keywordArgs.onItem.call(scope, item);

				
				//for(child in childArray)
				//{
				
					
					//self._addReferenceToMap(child,item,"children");
				
			
								
				
				//}
			}
			
			
			
			
		};
		
		

		//Callback for any errors that occur during load.
		var gotError = function(error){
			//Call the onComplete, if any
			if(keywordArgs.onError){
				var scope = keywordArgs.scope ? keywordArgs.scope : dojo.global;
				keywordArgs.onError.call(scope, error);
			}
		};

		//Fire the get and pass the proper callbacks to the deferred.
		var xhrArgs = {
			url: dataUrl,
			handleAs: "json-comment-optional"
		};
		var d = dojo.xhrGet(xhrArgs);
		d.addCallback(gotData);
		d.addErrback(gotError);
	}
});

